Desempenho de Funções em R e WebScraping com R
UFPE
Desempenhos de funções em R
Vamos comparar duas funções da para calcular média?
[1] TRUE
Unit: milliseconds
expr min lq mean median uq max neval
mean(x) 20.05238 20.09639 20.24549 20.25113 20.35316 20.50893 10
media(x) 192.18133 192.87069 193.71672 193.13452 193.31633 200.03675 10
# -------------------------------------------------------------------------- #
# Função de verossimilhança para uma distribuição normal
log_likelihood <- function(params, data) {
mu <- params[1]
sigma <- params[2]
# Log-verossimilhança negativa
nll <- -sum(dnorm(data, mean = mu, sd = sigma, log = TRUE))
return(nll)
}
# Função para estimação de parâmetros
estimate_params_r <- function(data) {
init_params <- c(mean(data), sd(data))
result <- optim(par = init_params, fn = log_likelihood, data = data)
return(result$par)
}
# -------------------------------------------------------------------------- #
#include <Rcpp.h>
using namespace Rcpp;
// Função de verossimilhança negativa em C++
// [[Rcpp::export]]
double log_likelihood_cpp(NumericVector params, NumericVector data) {
double mu = params[0];
double sigma = params[1];
int n = data.size();
double nll = 0.0; // Log-verossimilhança negativa
for(int i = 0; i < n; i++) {
double term = (data[i] - mu) * (data[i] - mu) / (2 * sigma * sigma);
nll += term + log(sigma) + 0.5 * log(2 * M_PI);
}
return nll;
}
// Função para estimação de parâmetros em C++
// [[Rcpp::export]]
NumericVector estimate_params_cpp(NumericVector data) {
NumericVector init_params = NumericVector::create(mean(data), sd(data));
Function optim("optim");
// Usando a função optim do R para otimização, passando a função C++ como callback
List result = optim(_["par"] = init_params, _["fn"] = Rcpp::InternalFunction(log_likelihood_cpp), _["data"] = data);
return result["par"];
}
# -------------------------------------------------------------------------- #
# Implementação manual da densidade da normal
log_likelihood_manual <- function(params, data) {
mu <- params[1]
sigma <- params[2]
# Log-verossimilhança negativa manualmente calculada
n <- length(data)
nll <- -sum(-log(sqrt(2 * pi * sigma^2)) - ((data - mu)^2) / (2 * sigma^2))
return(nll)
}
# Função para estimação de parâmetros
estimate_params_manual <- function(data) {
init_params <- c(mean(data), sd(data))
result <- optim(par = init_params, fn = log_likelihood_manual, data = data)
return(result$par)
}
# -------------------------------------------------------------------------- #
library(microbenchmark)
# Exemplo de uso
set.seed(42)
data <- rnorm(10000, mean = 5, sd = 2)
benchmark_result <- microbenchmark(
R = estimate_params_r(data),
Cpp = estimate_params_cpp(data),
Manual = estimate_params_manual(data),
times = 100L
)
print(benchmark_result)
Unit: milliseconds
expr min lq mean median uq max neval
R 5.643004 8.719610 8.855638 8.907514 9.103202 21.174926 100
Cpp 1.593910 3.408051 3.269749 3.473949 3.541126 5.641858 100
Manual 2.131362 3.743267 3.979577 3.790411 3.845735 9.730337 100
WebScraping com R
Segundo o Livro ‘Text Mining in Practice with R
’:
* “Mineração de texto é o processo de destilar1 insights de texto”.
* Para acadêmicos, pode auxiliar na compreensão de transcrições qualitativas ou em um estudo da linguagem;
* Para empresas, pode render informações interessantes que auxiliarão na modelagem preditiva por exemplo;
* Aos profissionais de marketing, podem auxiliar na criação de textos, fornecendo recomendações precisas para sua organização.
* Então, a mineração de texto pode ser usada em qualquer decisão baseada em dados, onde o texto se encaixa naturalmente como uma entrada.
rvest
rvest
ajuda você a extrair (ou colher) dados de páginas da web.
Ele foi projetado para funcionar com magrittr (pacote responsável pelo operador pipe %>%) para facilitar a expressão de tarefas comuns de web scraping e inspiradas em bibliotecas como a beautiful soup
e RoboBrowser
.
Atualmente o R
possui seu próprio pipe, é utilizado com o símbolo |>
.
HTML (HyperText Markup Language - Linguagem de Marcação de Hipertexto) - é uma linguagem de marcação usada para estruturar uma página web.
CSS (Cascading Style Sheets - Folha de Estilo em Cascata) - é usado para estilizar os elementos escritos no HTML.
Em HTML e CSS, existe a possibilidade de aplicar estilos através de ‘class’ e ‘id’;
class : é o atributo global formado por uma lista das classes de um elemento, separada por espaços.
id : define um identificador exclusivo (ID) que deve ser único por todo o documento.
rvest
Instalando o rvest
através do devtools
Lendo o pacote:
Usando a função read_html
do pacote xml2
(este pacote é uma dependência do rvest
) para ler a url.
Link: https://tradingeconomics.com/country-list/balance-of-trade
Essas informações do site Trading Economics representam dados econômicos de diferentes países:
Country (País): Refere-se ao país ao qual os dados econômicos se aplicam. Pode ser o nome completo do país ou uma abreviação.
Last (Último): Este campo mostra o valor mais recente do indicador econômico específico. Esse valor representa a última medição disponível desse dado.
Previous (Anterior): Este campo apresenta o valor anterior do mesmo indicador econômico, ou seja, o valor que foi registrado na medição anterior.
Reference (Referência): Indica o período ao qual os dados se referem. Por exemplo, pode ser o mês ou o trimestre em que os dados foram coletados.
Unit (Unidade): Especifica a unidade de medida dos dados. Pode ser uma moeda (por exemplo, USD, EUR), uma porcentagem, uma taxa de crescimento, entre outras formas de medição.
Duas funções serão utilizadas aqui:
#Scraping usando classe css ‘table’
trading_names_html <- html_nodes(trading_webpage, '.table')
trading_names <- html_table(trading_names_html)
head(trading_names[[1]],3)
# A tibble: 3 × 5
Country Last Previous Reference Unit
<chr> <dbl> <dbl> <chr> <chr>
1 Afghanistan -6798 -5169 Dec/23 USD Million
2 Albania -52150 -41945 Jul/24 ALL Million
3 Algeria 3790 2338 Sep/23 USD Million
library(ggplot2)
trading_df <- trading_names[[1]]
ggplot(trading_df, aes(x=Last)) +
geom_histogram() +
labs(title="", x ="Valor mais recente do indicador econômico",
y = "Frequência") +
theme_minimal()
[1] "Summary da coluna Last"
Min. 1st Qu. Median Mean 3rd Qu. Max.
-5.205e+09 -3.570e+03 -2.620e+02 -2.896e+07 9.950e+02 4.793e+06
Neste segundo exemplo vamos obter o texto de um site e analisá-lo.
# Passo 2:
#Scraping usando ‘p’
names_html <-html_nodes(webpage, 'p')
names <- html_text(names_html)
head(names)
[1] "Um megavazamento de dados pessoais de 223 milhões de brasileiros tornado público na semana passada pela empresa de segurança digital PSafe pode ser o maior na história do país e tem tudo para ser a primeira prova de fogo da Autoridade Nacional de Proteção de Dados (ANPD), criada a partir da entrada em vigor da Lei Geral de Proteção de Dados (LGPD) em agosto do ano passado. Também é o primeiro incidente desta magnitude que se tem notícia no Brasil. A lista com milhões de nomes completos, CPFs e datas de nascimento —de pessoas vivas e mortas— estava disponível para download gratuito a partir de um fórum de discussão na deep web —cópias do arquivo original foram feitas e podiam ser encontradas por qualquer um a partir de buscadores de internet. Em troca de bitcoins, o perfil anônimo responsável pelo vazamento dizia ser possível obter ainda retratos, endereço, telefone, declaração do Imposto de Renda, listas de familiares, renda mensal, score de crédito e muito mais dos alvos em questão. Na terça-feira, após a repercussão do caso, o material foi retirado do ar no fórum de livre acesso com qualquer navegador, mas continua em negociação na deep web."
[2] "Na lista há dados de gente famosa e autoridades públicas. De acordo com a PSafe, cibercriminosos também tiveram acesso a informações detalhadas sobre mais de 104 milhões de veículos e dados sigilosos de 40 milhões de empresas."
[3] "“O vazamento é real, confirmada a autenticidade de todos os dados, é o maior vazamento da história do Brasil e certamente um dos maiores do mundo”, afirma Marco DeMello, CEO da PSafe. “Estávamos monitorando a deep web para alguns de nossos clientes e nos deparamos com milhões de CPNJs em negociação, rastreamos e chegamos na fonte”, diz. Ele afirma que a equipe de segurança da empresa entrou em contato com o hacker, que disse cobrar 100 dólares por pacotes com os registros de mil pessoas, empresas ou veículos. Ele diz não ser brasileiro e que vai vender no máximo 1 milhão de contatos para cada comprador, pois pretende ganhar dinheiro com essa base de dados por muito tempo ainda. Segundo DeMello, nas conversas o hacker diz que roubou a base dados da Serasa/Experian, empresa de análise de crédito que cria perfis dos consumidores brasileiros entre outras atividades, mas não tem como saber se isso é verdade. A mesma alegação aparece na página onde ele vende o material, assim como no nome de alguns arquivos."
[4] "Apoie a produção de notícias como esta. Assine o EL PAÍS por 30 dias por 1 US$"
[5] "Procurada pela reportagem através de sua assessoria de imprensa, a Serasa/Experian respondeu, após a publicação, que a empresa não é a fonte dos dados vazados. “Embora o hacker afirme que parte dos dados veio da Serasa, com base em nossa análise detalhada até este ponto, concluímos que a Serasa não é a fonte”, diz a nota enviada. “Também não vemos evidências de que nossos sistemas tenham sido comprometidos”, afirma a empresa, que ainda diz não possuir todos os dados oferecidos na internet e que está em contato com autoridades reguladoras para ajudar no caso. "
[6] "Os dados estavam disponíveis no fórum de discussões desde o começo do mês e foram identificados pela empresa de segurança na terça-feira da semana passada, e teriam sido extraídos da fonte original por 18 meses entre 2018 e 2020. Segundo o CEO da PSafe, algumas informações foram checadas por amostragem e são reais. “É assustador, porque com isso qualquer golpista que comprar os dados pode fazer coisas inimagináveis em nome de outras como comprar e vender veículos e imóveis, contrair dívidas, invadir contas bancárias e outros sistemas informatizados que usam essas imagens, abrir empresas, o estrago possível é muito grande”, diz DeMello."
Organizando os dados para geração do gráfico da Nuvem de Tags
Corpus
: função que transforma vetores/listas em coleções de documentos que contêm texto.# Transformando em formato Corpus
texto <- Corpus(VectorSource(texto),
readerControl = list(reader = reader(VectorSource(texto)),
language = "pt"))
# -------
# Removendo as stopwords de arquivo.txt
# -------
file <- url("https://jodavid.github.io/Slide-Introdu-o-a-Web-Scrapping-com-rvest/stopwords_pt_BR.txt")
stopwords_ptBR <- read.table(file)
stopwords_ptBR <- unlist(stopwords_ptBR, use.names = FALSE)
texto <- tm_map(texto, removeWords, stopwords_ptBR)
# -------
# Descobrindo tamanho da lista
n <- length(texto)
# -------
# Removendo pontuacao
for(i in 1:n)
{
# Remover pontuacao, preservando abreviacoes
texto[[i]] <- removePunctuation(texto[[i]],
preserve_intra_word_contractions = TRUE,
preserve_intra_word_dashes = TRUE)
# Removendo quotations
texto[[i]] <- stringr::str_replace_all(texto[[i]], setNames(c('','','',''), c('“ ', '“',' ”','”')))
}
# -------
Livro: Text Mining in Practice with R
;
Extras:
OBRIGADO!
Slide produzido com quarto
Tópicos Especiais em Estatística Computacional - Prof. Jodavid Ferreira